package com.stxx.framwork.sql;




import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.noear.snack.ONode;
import org.noear.solon.annotation.Component;
import org.noear.solon.data.sql.bound.RowConverter;
import org.noear.solon.data.sql.bound.RowConverterFactory;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author Fuzhenlei
 * @date 2025/01/13 16:38
 */
@Component
public class RowConverterFactoryImpl implements RowConverterFactory<Object> {

    @Override
    public RowConverter<Object> create(Class<?> tClass) {
        return new RowConverterImpl(tClass);
    }

    private static class RowConverterImpl implements RowConverter<Object> {


        private final Class<?> tClass;
        private ResultSetMetaData metaData;

        public RowConverterImpl(Class<?> tClass) {
            this.tClass = tClass;
        }

        @Override
        public Object convert(ResultSet rs) throws SQLException {
            if (metaData == null) {
                metaData = rs.getMetaData();
            }
            Map<String, Object> map = new LinkedHashMap<>();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                String name = metaData.getColumnName(i);
                Object value = rs.getObject(i);
                map.put(StrUtil.toCamelCase(name), value);
            }
            if (Map.class == tClass) {
                return map;
            } else {
                JSONObject jsonObject = new JSONObject(map);
                return jsonObject.to(tClass);
                //return BeanUtil.toBean(map, tClass);
//                Object obj = ReflectUtil.newInstance(this.tClass);
//                Field[] fields = ReflectUtil.getFields(this.tClass);
//                for (Field field : fields) {
//                    ReflectUtil.setFieldValue(obj, field.getName(), ONode.load(map.get(field.getName())).toObject(field.getType()));
//                }
//                return obj;
            }
        }
    }
}